package cn.chenhao.order.service.impl;

import cn.chenhao.basic.service.impl.BasicServiceImpl;
import cn.chenhao.basic.util.CodeGenerateUtils;
import cn.chenhao.basic.util.PageList;
import cn.chenhao.order.constants.OrderConstants;
import cn.chenhao.order.domain.AdoptOrder;
import cn.chenhao.order.domain.OrderAddress;
import cn.chenhao.order.mapper.AdoptOrderMapper;
import cn.chenhao.order.mapper.OrderAddressMapper;
import cn.chenhao.order.query.AdoptOrderQuery;
import cn.chenhao.order.service.IAdoptOrderService;
import cn.chenhao.org.domain.Employee;
import cn.chenhao.org.mapper.EmployeeMapper;
import cn.chenhao.pay.constants.PayConstants;
import cn.chenhao.pay.domain.PayBill;
import cn.chenhao.pay.mapper.PayBillMapper;
import cn.chenhao.pay.service.IPayBillService;
import cn.chenhao.pet.domain.Pet;
import cn.chenhao.pet.mapper.PetMapper;
import cn.chenhao.quartz.constants.JobConstants;
import cn.chenhao.quartz.service.IQuartzService;
import cn.chenhao.quartz.utils.QuartzJobInfo;
import cn.chenhao.user.domain.Logininfo;
import cn.chenhao.user.domain.User;
import cn.chenhao.user.domain.UserAddress;
import cn.chenhao.user.mapper.UserAddressMapper;
import cn.chenhao.user.mapper.UserMapper;
import org.quartz.ee.jmx.jboss.QuartzService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends BasicServiceImpl<AdoptOrder> implements IAdoptOrderService {

    @Autowired
    private PetMapper petMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserAddressMapper userAddressMapper;

    @Autowired
    private AdoptOrderMapper adoptOrderMapper;

    @Autowired
    private OrderAddressMapper orderAddressMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private PayBillMapper payBillMapper;

    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private IQuartzService quartzService;

    @Override
    public String submit(Map<String, Object> params, Logininfo logininfo) {
        //1.校验参数
        Integer serviceMethod = Integer.valueOf(params.get("service_method").toString());// 送货方式
        Long addressId = Long.valueOf(params.get("address_id").toString());// 收货地址保存到id t_user_address
        Long payMethod = Long.valueOf(params.get("pay_method").toString());// 支付方式：0 银联，1 支付宝，2 微信
        Long petId = Long.valueOf(params.get("pet_id").toString());
        //2.修改宠物状态 + 下架时间 + 绑定领养人
        Pet pet = petMapper.loadById(petId);
        User user = userMapper.loadByLogininfoId(logininfo.getId());
        pet.setUser_id(user.getId());
        pet.setState(0);
        pet.setOffsaletime(new Date());
        petMapper.update(pet);
        // 3.创建领养订单
        // 3.1 订单本表
        AdoptOrder adoptOrder = initAdoptOrder(pet, user);
        // 为了后面生成支付单不用再修改订单，先直接生成统一支付标识，后面直接使用
        adoptOrder.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        adoptOrderMapper.save(adoptOrder);// 需要返回自增id
        // 3.2 订单地址表
        UserAddress userAddress = userAddressMapper.loadById(addressId);
        OrderAddress orderAddress = initOrderAddress(adoptOrder, userAddress);
        orderAddressMapper.save(orderAddress);

        // 4.支付订单并支付
        // 生成支付订单
        PayBill payBill = initPayBill(payMethod, user, adoptOrder);
        payBillMapper.save(payBill);

        // 订单超时未支付时，触发取消订单任务
        QuartzJobInfo info = new QuartzJobInfo();// 创建一个定时任务
        info.setJobName(JobConstants.PAY_OVER_TIME_ADOPT_ORDER + adoptOrder.getId());// 设置任务名字
        Map<String, Object> map = new HashMap<>();// 定义一个map来保存任务所需要的值
        map.put("type", JobConstants.PAY_OVER_TIME_ADOPT_ORDER);// 任务类型
        map.put("orderId", adoptOrder.getId());// 订单编号
        info.setParams(map);// 保存任务的参数
        info.setFireDate(adoptOrder.getLastPayTime());// 保存定时 时长
        quartzService.addJob(info);// 添加任务

        return payBillService.pay(payBill);

    }

    private PayBill initPayBill(Long payMethod, User user, AdoptOrder adoptOrder) {
        PayBill bill = new PayBill();
        bill.setDigest(adoptOrder.getDigest());// private String digest;
        bill.setMoney(adoptOrder.getPrice());// private BigDecimal money;
        bill.setUnionPaySn(adoptOrder.getPaySn());//private String unionPaySn;
        // 5.超时未支付自动取消
        bill.setLastPayTime(new Date(System.currentTimeMillis() + OrderConstants.LAST_PAY_TIME));//private Date lastPayTime;
        bill.setPayChannel(Long.valueOf(payMethod));//private Long payChannel; // 0 余额 1 支付宝 2 微信 3 银联
        bill.setBusinessType(PayConstants.BUSINESS_TYPE_ADOPT);//private String businessType;
        bill.setBusinessKey(adoptOrder.getId());//private Long businessKey;
        bill.setUser_id(adoptOrder.getUser_id());//private Long user_id;
        bill.setShop_id(adoptOrder.getShop_id());//private Long shop_id;
        bill.setNickName(user.getUsername());//private String nickName;
        return bill;
    }

    /**
     * 管理端查看订单
     * @param query
     * @param currentLoginInfo
     * @return
     */
    @Override
    public PageList<AdoptOrder> admin(AdoptOrderQuery query, Logininfo currentLoginInfo) {
        Employee emp = employeeMapper.loadByLogininfoId(currentLoginInfo.getId());
        if(emp.getShop_id() != null){
            query.setShopId(emp.getShop_id());
        }
        return super.queryPage(query);
    }

    /**
     * 当前用户查看订单
     * @param query
     * @param currentLoginInfo
     * @return
     */
    @Override
    public PageList<AdoptOrder> user(AdoptOrderQuery query, Logininfo currentLoginInfo) {
        User user = userMapper.loadByLogininfoId(currentLoginInfo.getId());
        query.setUserId(user.getId());
        return super.queryPage(query);
    }

    /**
     * 移除定时任务
     * @param orderId
     */
    @Override
    public void deleteByQuartz(Long orderId) {
        AdoptOrder adoptOrder = adoptOrderMapper.loadById(orderId);
        if(adoptOrder.getState() == 0){// 如果订单状态为未支付
            // 这里有很多业务流，可以考虑订单取消后，宠物再上架的问题等。。
            adoptOrder.setState(-1);// 定时器任务结束后，则将订单状态改为取消
            adoptOrderMapper.update(adoptOrder);
            System.out.println("############################超时自动取消订单###################");
        }
    }


    /**
     * 初始化订单地址
     * @param order
     * @param userAddress
     * @return
     */
    private OrderAddress initOrderAddress(AdoptOrder order, UserAddress userAddress) {
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress, orderAddress);
        orderAddress.setOrder_id(order.getId());
        orderAddress.setOrderSn(order.getOrderSn());
        return orderAddress;
    }

    /**
     * 初始化领养订单
     * @param pet
     * @param user
     * @return
     */
    private AdoptOrder initAdoptOrder(Pet pet, User user) {
        AdoptOrder order = new AdoptOrder();
        order.setDigest("[摘要]对" + pet.getName() + "领养订单！");
        order.setPrice(pet.getSaleprice());
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        order.setOrderSn(orderSn);
        order.setPet_id(pet.getId());
        order.setUser_id(user.getId());
        order.setShop_id(pet.getShop_id());
        order.setLastPayTime(new Date(System.currentTimeMillis() + OrderConstants.LAST_PAY_TIME));// 支付超15分钟自动取消
        return order;
    }
}
